<?php

declare(strict_types=1);

/**
 * @Author:     Frank
 * @contact     frank_hhm@163.com
 * @Date:       2023-02-16 11:12:55
 * @Last Modified time: 2023-02-21 16:22:42
 */
namespace app\common\services\pay;

use frank\base\BaseService;
use frank\exception\CommonException;
use app\common\dao\pay\RefundDao;
use app\common\enum\pay\PayTypeEnum;
use app\common\enum\pay\PayStatusEnum;
use app\common\enum\pay\RefundSourceEnum;

/**
 * 支付 - 退款
 * Class RefundService
 */
class RefundService extends BaseService
{

    // 来源模型
    private $SourceModelClass = [
        RefundSourceEnum::MASTER => 'app\common\services\store\order\RefundSuccessService'
    ];

    /**
     * RefundService constructor.
     * @param FilesDao $dao
     */
    public function __construct(RefundDao $dao)
    {
        $this->dao = $dao;
    }

    public function getDetail($filter)
    {
        $detail = $this->dao->search($filter)->find();
        if (!$detail) {
            throw new CommonException('退款单不存在');
        }
        return $detail;
    }

    /**
     * 新增退款单
     */
    public function execute($data,$payType = PayTypeEnum::WALLET)
    {
        $outRefundNo = $this->dao->refundNo().'@'.$data['order_no'];

    	$data['pay_type'] = $payType;

    	$data['out_refund_no'] = $outRefundNo;

    	$status = $this->dao->save($data);

        // 1.余额支付退款
        if ($payType == PayTypeEnum::WALLET) {
           $status = $this->onRefundByWallet($data);
        }

        // 2.微信支付退款
        if ($payType == PayTypeEnum::WECHAT) {
            $status = event('WechatPayRefund',[
                'out_trade_no'=>$data['order_no'],
                'out_refund_no'=>$outRefundNo,
                'pay_price'=>$data['pay_price'], 
                'refund_price'=>$data['refund_price'], 
            ]);
        }

        return $status;
    }

    /**
     * 余额退款标记订单已退款
     */
    public function onRefundByWallet($data)
    {   
        $sourceId = $data['source_id'];
        if($data['source'] == RefundSourceEnum::MASTER){
            $sourceId = $data['order_no'];
        }
        $service = $this->SourceModelClass[$data['source']]::instance($sourceId);
        // 订单退款成功业务处理
        $status = $service->onRefundSuccess(PayTypeEnum::WALLET,[
            'refund_price'=>$data['refund_price'] //余额支付金额
        ]);
        if (!$status) {
            $this->error = $service->error;
        }
        return $status;
    }

    /**
     * 保存退款单结果
     */
    public function updateResult(
    	$source,
    	$sourceId,$data){
    	return $this->dao->update([
        	'source'=>$source,
        	'source_id'=>$sourceId,
        ],$data);
    }
}
